package com.erlang4j.internal.process;

import static com.erlang4j.api.Erlang4jMessageLanguage.binding;
import static com.erlang4j.api.Erlang4jMessageLanguage.state;
import junit.framework.TestCase;

import com.ericsson.otp.erlang.OtpErlangPid;
import com.ericsson.otp.erlang.OtpNode;
import com.erlang4j.api.IBinding;
import com.erlang4j.api.exceptionHandler.SysoutExceptionHandler;
import com.erlang4j.internal.adapters.MockAddBindingAdapter;
import com.erlang4j.internal.basicIo.MockBasicMailBox;
import com.erlang4j.internal.messages.IMessageComposer;
import com.erlang4j.internal.messages.MessageComposer;

public class StateMachineChangingBindingTest extends TestCase {
	private MockAddBindingAdapter adapter1;
	private final IMessageComposer composer = new MessageComposer(binding());
	private OtpErlangPid self;

	public void testAdd() {
		checkAdd(binding(), binding("V1", "val1"), binding("X", "x"));
		checkAdd(binding("X", "x"), binding("V1", "val1", "X", "x"), binding("X", "x"));
		checkAdd(binding("W", "w"), binding("V1", "val1", "W", "w"), binding("W", "w", "X", "x"));
	}

	private void checkAdd(IBinding initialBinding, IBinding passedToHandler, IBinding expectedBinding) {
		MockBasicMailBox mockBasicMailBox = new MockBasicMailBox(self);
		StateMachine process = new StateMachine(mockBasicMailBox, new SysoutExceptionHandler(), initialBinding, state(null, adapter1));
		process.process(composer.compose("{a1,[P0]}", "val1"));
		IBinding postBinding = process.matchingBinding();
		assertEquals(passedToHandler, adapter1.context);
		assertEquals(expectedBinding, postBinding);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		adapter1 = new MockAddBindingAdapter("{a1,[V1]}", "X", "x");
		self = new OtpNode("somename").createPid();
	}
}
